function Game(){
	this.viewport = vec2(864, 480);
	this.viewS = vec2(27, 15);
	this.gridS = vec2(32,32);
	
	this.eng = new Engine(this.viewport, Utils.get("divGame"));
	this.eng.ctx.font = '16px "Courier"';
	
	this.images =  {};
	this.maps = [];
	this.scene = null;
	this.map = null;
	
	this.statsX = false;
	this.keys = [];
	this.lastK = -1;
	
	this.lastTime = 0;
	this.fps = Math.round(1000 / 30);
	
	this.loadImages();
}

Game.prototype.showLoading = function(){
	var ctx = this.eng.ctx;
	
	ctx.fillStyle = "black";
	ctx.fillRect(0,0,this.viewport.a,this.viewport.b);
	
	ctx.fillStyle = "white";
	ctx.textAlign = "center";
	ctx.fillText("Loading", this.viewport.a / 2, this.viewport.b / 2 - 16);
	
	var per = this.eng.getImagesPercent();
	ctx.strokeStyle = "white";
	ctx.strokeRect(this.viewport.a / 2 - 150, this.viewport.b / 2 - 5, 300, 10);
	ctx.fillRect(this.viewport.a / 2 - 150, this.viewport.b / 2 - 5, 300 * per, 10);
};

Game.prototype.drawTile = function(/*tile*/ tile, /*int*/ x, /*int*/ y, /*boolean*/ absolutePosition, /*int*/ dark){
	var ctx = this.eng.ctx;
	
	var img = this.images[tile.tile];
	
	var ix = tile.position.a * this.gridS.a;
	var iy = tile.position.b * this.gridS.b;
	
	var xx = x;
	var yy = y;
	if (!absolutePosition){
		xx = x * this.gridS.a;
		yy = y * this.gridS.b;
	}
	
	var gx = this.gridS.a;
	var gy = this.gridS.b;
	
	ctx.drawImage(img,
			ix, iy, gx, gy,
			xx, yy, gx, gy);
			
	if (dark > 0){
		var d = (dark / 10);
		ctx.fillStyle = "rgba(0,0,0," + d + ")";
		ctx.fillRect(xx,yy,gx,gy);
	}else if (dark == -1){
		ctx.fillStyle = "rgba(0,0,0,0.5)";
		ctx.fillRect(xx,yy,gx,gy);
	}
};

Game.prototype.drawInterface = function(){
	var ctx = this.eng.ctx;
	var ps = PlayerStats;
	
	var cL = this.map.player.getEquipped("isL");
	
	//Back
	ctx.fillStyle = "rgb(30,30,30)";
	ctx.fillRect(0,0,ctx.width,32);
	
	//HP
	var hlt = ps.hp / ps.mHp;
	ctx.fillStyle = "rgb(200,0,0)";
	ctx.strokeStyle = "rgb(200,0,0)";
	ctx.fillRect(8,8,200 * hlt,8);
	ctx.strokeRect(8,8,200,8);
	
	//Stamina
	var mp = ps.stam / ps.mStam;
	ctx.fillStyle = "rgb(95,115,185)";
	ctx.strokeStyle = "rgb(95,115,185)";
	ctx.fillRect(8,22,150 * mp,4);
	ctx.strokeRect(8,22,150,4);
	
	//Name
	ctx.fillStyle = "white";
	ctx.textAlign = "center";
	ctx.fillText(ps.name + ", " + ps.pClass.name, ctx.width / 2, 20);
	
	//Stas
	if (this.statsX && !this.map.player.isBusy()){
		var ef = (cL)? cL.effect : AmuletEffect.nulle;
		
		var xx = ctx.width - 350;
		
		ctx.fillStyle = "rgba(30,30,30,0.5)";
		ctx.fillRect(xx, 0, 350, 70);
		
		ctx.fillStyle = "white";
		ctx.textAlign = "left";
		ctx.fillText("lvl: " + ps.level, xx + 8, 20);
		ctx.fillText("exp: " + ps.exp, xx + 98, 20);
		ctx.fillText("gold: " + ps.gold, xx + 220, 20);
		
		ctx.fillText("str: " + (ps.str + ef.getAttribute("str")), xx + 8, 40);
		ctx.fillText("dfs: " + (ps.dfs + ef.getAttribute("dfs")), xx + 98, 40);
		ctx.fillText("spd: " + (ps.spd + ef.getAttribute("spd")), xx + 220, 40);
		
		ctx.fillText("luk: " + (ps.luk + ef.getAttribute("luk")), xx + 8, 60);
		ctx.fillText("wis: " + (ps.wis + ef.getAttribute("wis")), xx + 98, 60);
		ctx.fillText("cha: " + (ps.cha + ef.getAttribute("cha")), xx + 220, 60);
	}else{
		var xx = ctx.width - 350;
		
		ctx.fillStyle = "white";
		ctx.textAlign = "left";
		ctx.fillText("lvl: " + ps.level, xx + 8, 20);
		ctx.fillText("exp: " + ps.exp, xx + 98, 20);
		ctx.fillText("gold: " + ps.gold, xx + 220, 20);
	}
	
	//Equipped Items
	var cW = this.map.player.getEquipped("isW");
	var cA = this.map.player.getEquipped("isA");
	
	var total = 60 * ((cW? 1 : 0) + (cA? 1: 0) + (cL? 1 : 0));
	var x = ctx.width - 48;
	var y = (ctx.height / 2) - (total / 2);
	
	if (total > 0){
		ctx.fillStyle = "rgb(33,33,33)";
		ctx.strokeStyle = "white";
		ctx.fillRect(x, y, 48, total);
		ctx.strokeRect(x, y, 48, total);
	}
	
	ctx.fillStyle = "white";
	ctx.textAlign = "center";
	if (cW){
		var tile = Tileset.items[cW.tile];
		this.drawTile(tile, x + 8, y + 4, true);
		ctx.fillText((cW.status * 100) + "%", x + 24, y + 50);
		
		y += 60;
	}
	if (cA){
		var tile = Tileset.items[cA.tile];
		this.drawTile(tile, x + 8, y + 4, true);
		ctx.fillText((cA.status * 100) + "%", x + 24, y + 50);
		
		y += 60;
	}
	if (cL){
		var tile = Tileset.items[cL.tile];
		this.drawTile(tile, x + 8, y + 4, true);
	}
	
	ctx.textAlign = "left";
};

Game.prototype.loadImages = function(){
	this.images["charas"] = this.eng.loadImage(cp + "img/Charas.png?version=" + version, vec2(4, 2));
	this.images["tileset"] = this.eng.loadImage(cp + "img/Tileset.png?version=" + version, vec2(5, 4));
	this.images["items"] = this.eng.loadImage(cp + "img/Items.png?version=" + version, vec2(1, 3));
};

Game.prototype.waitForImages = function(){
	var game = this;
	if (game.eng.areImagesReady()){
		game.showLoading();
		
		//this.map = new Map(this);
		//this.maps.push(this.map);
		this.scene = new MainScene(this); 
		
		game.loopGame();
	}else{
		game.showLoading();
		requestAnimationFrame(function(){ game.waitForImages(); });
	}
};

Game.prototype.newGame = function(){
	this.waitForImages();
};

var counter = 0, first = Date.now();
Game.prototype.executeLoop = function(time){
	if (this.lastTime == 0 || this.lastTime == undefined){
		this.lastTime = Date.now();
		return true;
	}else{
		var now = Date.now();
		var delta = now - this.lastTime;
		if (delta > this.fps){
			counter++;
			this.lastTime = now - (delta % this.fps);
			var time_el = (this.lastTime - first) / 1000;
			var fps = counter / time_el;
			
			Utils.get("lblFPS").innerHTML = "FPS: " + Math.round(fps);
			return true;
		}
	}
	
	return false;
};

Game.prototype.loopGame = function(time){
	var game = this;
	
	if (game.executeLoop(time)){
		if (this.scene != null){
			this.scene.loop();
		}else if (this.map != null){
			this.eng.ctx.clear();
			this.map.execute();
			Console.drawConsole(this.eng.ctx, this.map.player.isBusy());
			this.drawInterface();
		}
	}
	
	requestAnimationFrame(function(time){ game.loopGame(time); });
};

Utils.addEvent(window, "load", function(){
	var game = new Game();
	game.newGame();
	
	Utils.addEvent(document, "keydown", function(e){
		if (window.event) e = window.event;
		
		game.lastK = e.keyCode;
		if (game.keys[e.keyCode] == 2) return;
		game.keys[e.keyCode] = 1;
	});
	
	Utils.addEvent(document, "keyup", function(e){
		if (window.event) e = window.event;
		
		game.keys[e.keyCode] = 0;
	});
});
